package com.skyd.core.game.td;

import java.util.concurrent.CopyOnWriteArrayList;
import java.util.Collection;

public class TDTower extends TDActor implements ITDTower {
	
	/**
	 * 上次攻击时间
	 */
	private long lastAttackTime=0;
	/**
	 * 上次寻找攻击目标的时间
	 */
	private long lastfindAttackTargetTime=0;
	/**
	 * 寻找攻击目标行为间隔时间
	 */
	private int findAttackTargetDelay=10;

	@Override
	public void update() {
		if(getEffect()!=null)getEffect().update();
		if(getCurrentTime()-lastfindAttackTargetTime>findAttackTargetDelay&&getCurrentTime()-lastAttackTime>getFinalStatus().getAttackDelay()){
			toAttack(findAttackTarget());
			lastfindAttackTargetTime=getCurrentTime();
		}
	}
	
	/**
	 * 进行攻击
	 * @param target 目标
	 */
	protected void toAttack(Collection<? extends TDActor> target){
		if(target==null)return;
		OnAttack(target);
		attack(target);
		lastAttackTime=TDWorld.getInstance().getTime();
	}

	/**
	 * 攻击。后代类可以重写此方法以实现发射子弹攻击。
	 * @param target 目标
	 */
	protected void attack(Collection<? extends TDActor> target) {
		for (TDActor f : target) {
			f.OnUnderAttack(this,this.getFinalStatus().getATK());
		}
	}
	
	/**
	 * 发射子弹
	 * @param bullet 子弹
	 */
	protected void discharge(TDActor target,TDBullet bullet) {
		bullet.setPosition(getCenterPosion());
		bullet.setSource(this);
		bullet.setTarget(target);
		TDWorld.getInstance().getBullets().add(bullet);
		onBulletFired(target, bullet);
	}
	
	/**
	 * 获取地图上距离最近的生物
	 * @return 
	 */
	protected ITDBiont getNearestBiont(){
		//TODO:这样直接获取最近的生物当做攻击目标的话会有一个问题，就是假如最近的是空中单位，而炮塔又只能对地，则判断不会进行攻击，而这时其他稍远点的单位也被同时忽略了，应该考虑增加参数来筛选类型
		CopyOnWriteArrayList<ITDBiont> bl = TDWorld.getInstance().getBiont();
		ITDBiont b = null;
		float r=Float.MAX_VALUE;
		for (ITDBiont f : bl) {
			if(f.getIsDead())continue;
			float l = f.getPosition().minus(getPosition()).getLength();
			if(l<r){
				r=l;
				b=f;
			}
		}
		return b;
	}

	/**
	 * 寻找攻击目标
	 * @return
	 */
	protected CopyOnWriteArrayList<TDActor> findAttackTarget() {
		ITDBiont b = getNearestBiont();
		if(b!=null){
			watch(b);
		
			if(calculationIsInRange(b)){
				CopyOnWriteArrayList<TDActor> rl = new CopyOnWriteArrayList<TDActor>();
				rl.add((TDActor) b);
				return rl;
			}
		}
		
		return null;
	}

	/**
	 * 注视目标（朝向目标）
	 * @param target 目标
	 */
	protected void watch(ITDActor target) {
		float d = target.getPosition().minusNew(getPosition()).getAngle();
		setDirection(d<0?360-d*-1:d);
	}

	
	/**
	* BulletsFiredListener事件监听器列表。发射子弹
	*/
	private  CopyOnWriteArrayList<ITDTowerBulletFiredListener>  _BulletFiredListenerList = null;
	
	/**
	 * 增加一个BulletsFiredListener事件的监听器，返回是否成功增加。事件功能注释：发射子弹
	 * @param listener BulletsFiredListener事件监听器对象
	 * @return 是否成功增加。如果该监听器对象已存在，则返回false。
	 */
	public  boolean addOnBulletFiredListener(ITDTowerBulletFiredListener listener)
	{
		if(_BulletFiredListenerList==null)_BulletFiredListenerList=new CopyOnWriteArrayList<ITDTowerBulletFiredListener>();
		else if(_BulletFiredListenerList.contains(listener))return false;
		_BulletFiredListenerList.add(listener);
		return true;
	}
	
	/**
	 * 移除一个BulletsFiredListener事件的监听器，返回是否成移除。事件功能注释：发射子弹
	 * @param listener BulletsFiredListener事件监听器对象
	 * @return 是否成功移除。如果该监听器对象不存在，则返回false。
	 */
	public  boolean removeOnBulletFiredListener(ITDTowerBulletFiredListener listener)
	{
		if(_BulletFiredListenerList==null||!_BulletFiredListenerList.contains(listener))return false;
		_BulletFiredListenerList.remove(listener);
		return true;
	}
	
	/**
	 * 清空所有BulletsFiredListener事件的监听器。事件功能注释：发射子弹
	 */
	public  void clearOnBulletFiredListeners()
	{
		if(_BulletFiredListenerList!=null)_BulletFiredListenerList.clear();
	}
	
	/**
	 * 发射子弹
	 */
	protected  void onBulletFired(ITDActor target,ITDBullet bullet)
	{
		if(_BulletFiredListenerList!=null)
			for(ITDTowerBulletFiredListener listener:_BulletFiredListenerList){
				listener.onBulletFired(this, target, bullet);
			}
	}

}
